
#include "Display.h"

Display::Display(int width, int height, const std::string title, GLboolean isfullScreen) {
	m_width = width;
	m_height = height;
	m_isFullScreen = isfullScreen;

	if (glfwInit() == GL_FALSE) {
		Util::err("GLEW init failed !");
		return;
	}
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

	m_window = glfwCreateWindow(m_width, m_height, title.c_str(), NULL, NULL);
	if (m_window == NULL) {
		Util::err("GLEW create window failed !");
		return;
	}

	m_pMonitor = glfwGetPrimaryMonitor();
	m_mode = glfwGetVideoMode(m_pMonitor);
	ToggleFullScreen(m_isFullScreen);

	glfwMakeContextCurrent(m_window);
	glfwSetFramebufferSizeCallback(m_window, Framebuffer_Resize);


	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		Util::err("Glad load GL loader failed !");
		return;
	}

	glViewport(0, 0, m_width, m_height);

	Input::Init(m_window);

	glEnable(GL_DEPTH_TEST);
}

GLboolean Display::IsEixt() {
	return glfwWindowShouldClose(m_window);
}

GLvoid Display::SwapBuffers() {
	glfwSwapBuffers(m_window);
	glfwPollEvents();
}

GLvoid Display::Clean() {
	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	if (m_isWireframeMode)
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	else
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	GLfloat currentFrame = (GLfloat)glfwGetTime();
	deltaTime = currentFrame - lastFrame;
	lastFrame = currentFrame;

	if (Input::GetKeyDown(GLFW_KEY_F1))
		ChangeMode();

	if (Input::GetKeyDown(GLFW_KEY_F3))
		ToggleFullScreen(GL_TRUE);
	if (Input::GetKeyDown(GLFW_KEY_F4))
		ToggleFullScreen(GL_FALSE);

	if (Input::GetKey(GLFW_KEY_F5))
		Input::SetMouseCursor(GLFW_CURSOR_DISABLED);
	if (Input::GetKey(GLFW_KEY_F6))
		Input::SetMouseCursor(GLFW_CURSOR_NORMAL);
	if (Input::GetKey(GLFW_KEY_F7))
		Input::SetMouseCursor(GLFW_CURSOR_HIDDEN);
}

GLvoid Display::ChangeMode() {
	m_isWireframeMode = !m_isWireframeMode;
}

GLvoid Display::ToggleFullScreen(GLboolean isfullScreen) {
	if (m_isFullScreen == isfullScreen) return;
	m_isFullScreen = isfullScreen;

	if (m_isFullScreen)
		glfwSetWindowMonitor(m_window, m_pMonitor, 0, 0, m_mode->width, m_mode->height, GLFW_DONT_CARE);
	else
		glfwSetWindowMonitor(m_window, NULL, (m_mode->width - m_width) / 2, (m_mode->height - m_height) / 2, m_width, m_height, GLFW_DONT_CARE);
}

GLvoid Display::Framebuffer_Resize(GLFWwindow* window, int width, int height) {
	glViewport(0, 0, width, height);
}

Display::~Display() {
	glfwTerminate();
}